
#include "msg_queue.h"

static msg_queue_t  msg_queue ={
	.len    = 0,
	.e_head = NULL,
};

static int msg_queue_lock(void)
{

	return OS_OK;
}

static int msg_queue_unlock(void)
{
	
	return OS_OK;
}

int msg_queue_init(void)
{
    msg_queue.len = 0;

    msg_queue.e_head = (slist_t*)malloc(sizeof(slist_t));
	if(msg_queue.e_head == NULL){
		log_e("e_head null\n");
		return OS_ERR;
	}

    slist_init(msg_queue.e_head);
    return OS_OK;
}

int msg_queue_deinit(void)
{
	int i   = 0;
	int len = 0;
	if(!msg_queue.e_head){
		return OS_ERR;
	}
	len = msg_queue_get_len();
	if(len <= 0){
		return OS_ERR;
	}

	for(i=0;i<len;i++)
	{
		msg_queue_del(0);
	}

	free(msg_queue.e_head);
	msg_queue.e_head = NULL;

    return OS_OK;
}

int msg_queue_send(msg_notify_t* msg)
{
    msg_link_t* obj = NULL;
	
	msg_queue_lock();
	if(!msg_queue.e_head){
		msg_queue_unlock();
		return OS_ERR;
	}
	
    obj = (msg_link_t *)malloc(sizeof(msg_link_t));
    if(obj == NULL){
        log_e("obj err\n");
		msg_queue_unlock();
        return OS_ERR;
    }
    memset(obj, 0, sizeof(msg_link_t));
    slist_init(&(obj->e_tail));
    //**************************************************
    obj->e_attr.cmd     = msg->cmd;
    obj->e_attr.data0   = msg->data0;
    obj->e_attr.data1   = msg->data1;
	obj->e_attr.para    = msg->para;
    //**************************************************
    msg_queue.len++;
    slist_add_tail(msg_queue.e_head,&(obj->e_tail));
    //**************************************************
	msg_queue_unlock();

    return OS_OK;
}

int msg_queue_recv(msg_notify_t* msg)
{
	int ret = 0;
	slist_t* node;
	msg_link_t* obj = NULL;

	msg_queue_lock();
	if(!msg_queue.e_head){
		msg_queue_unlock();
		return OS_ERR;
	}

	if(slist_isempty(msg_queue.e_head)){
		msg_queue_unlock();
		return OS_ERR;
	}

	slist_for_each(node,(msg_queue.e_head))
	{
		obj = slist_entry(node, msg_link_t, e_tail);
		if(obj){
            memcpy(msg,&obj->e_attr,sizeof(msg_notify_t));
            ret = 1;
            break;
		}
	}

	if(ret){
		slist_remove(msg_queue.e_head, &(obj->e_tail));
		msg_queue.len--;

        if(obj){
            free(obj);
            obj = NULL;
        }
	}

	msg_queue_unlock();

	return OS_OK;
}

int msg_queue_del(int index)
{
	int ret   = 0;
	int total = 0;
	slist_t* node;
	msg_link_t* obj = NULL;

	msg_queue_lock();
	if(!msg_queue.e_head){
		msg_queue_unlock();
		return OS_ERR;
	}
	if(slist_isempty(msg_queue.e_head)){
		msg_queue_unlock();
		return OS_ERR;
	}
	slist_for_each(node,(msg_queue.e_head))
	{
		obj = slist_entry(node, msg_link_t, e_tail);
		if(obj)
		{
			if(total == index)
			{
				ret = 1;
				break;
			}
			total++;
		}
	}
	if(ret){
		slist_remove(msg_queue.e_head, &(obj->e_tail));
		msg_queue.len--;

        if(obj){
            free(obj);
            obj = NULL;
        }
	}

	msg_queue_unlock();

	return OS_OK;
}

int msg_queue_trav(void)
{
    int i = 0;
	slist_t* node;
    msg_link_t* obj = NULL;

	msg_queue_lock();
	if(!msg_queue.e_head){
		msg_queue_unlock();
		return OS_ERR;
	}

	if(slist_isempty(msg_queue.e_head)){
		msg_queue_unlock();
		return OS_ERR;
	}

	slist_for_each(node,(msg_queue.e_head))
	{
		obj = slist_entry(node,msg_link_t,e_tail);
		if(obj)
		{
			#if 0
			log_e("i:cmd=%d:%d\n",i++,obj->e_attr.cmd);
			#endif
		}
	}

	msg_queue_unlock();

	return OS_OK;
}

int msg_queue_get_len(void)
{
	int len = 0;
	msg_queue_lock();
	len = msg_queue.len;
	msg_queue_unlock();

	log_d("len=%d\n",len);

    return len;
}

